﻿using System;
using System.Web.UI.WebControls;
using MyLib.Web.UI;

namespace MyLib.Web.Pages {
	/// <summary>
	/// 
	/// Action: 205
	/// </summary>
	public abstract class CodesPage : MyPage {
		/// <summary>
		/// 
		/// </summary>
		protected void DoQuery() {
			var gridView = this.FindDescendantControl<MyGridView>("GridView1");

			gridView.PageIndex = 0;
			gridView.DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected bool IsCodeValueEditable() {
			return ViewState.Get<bool>("InsertFlag", false);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		protected bool IsDeletable(string value) {
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		protected bool IsEditable(string value) {
			return true;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		protected string GetRowCommandArgument() {
			var row = (System.Data.DataRowView)Page.GetDataItem();

			return string.Concat(row["categoryId"], '_', row["value"]);
		}

		/// <summary>
		/// 
		/// </summary>
		protected void UpdateCodeCache() {
			var dt = GetDbProvider<MyLib.Data.CodeProvider>().FindCodes();
			var cfp = new MyLib.Data.CodeFileProvider(MapPath("~/SysCode.xml"), new WebCacheProvider(Context));
			cfp.SaveDataTable(dt);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="categoryId"></param>
		protected void DoCreateNewCode(int categoryId) {
			ViewState["EditCategoryId"] = categoryId;
			ViewState["EditValue"] = " ";
			ViewState["InsertFlag"] = true;

			this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="categoryId"></param>
		/// <param name="value"></param>
		protected void DoEditCode(int categoryId, string value) {
			if (value == null || value.Length == 0) {
				return;
			}

			ViewState["EditCategoryId"] = categoryId;
			ViewState["EditValue"] = value;
			ViewState["InsertFlag"] = false;

			this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="categoryId"></param>
		/// <param name="value"></param>
		protected void DoDeleteCode(int categoryId, string value) {
			if (value == null || value.Length == 0) {
				return;
			}

			var c = GetDbProvider<MyLib.Data.CodeProvider>().DeleteCode(categoryId, value);
			if (c == 0) {
				Context.AddError(string.Format(Properties.Main.ErrorCodeNotDeleted, value));
			}

			DoQuery();

			if (ViewState.Get<string>("EditValue") == value) {
				ViewState["EditValue"] = null;

				this.FindDescendantControl<System.Web.UI.Control>("FormView1").DataBind();
			}

			UpdateCodeCache();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="causesValidation"></param>
		/// <param name="validationGroup"></param>
		protected virtual void HandleQuery(bool causesValidation, string validationGroup) {
			this.FindDescendantControl<MyPanel>("Panel1").CopyValuesToViewState(ViewState);

			Context.ExecuteSafely(DoQuery);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="causesValidation"></param>
		/// <param name="validationGroup"></param>
		protected virtual void HandleCreateNew(bool causesValidation, string validationGroup) {
			var categoryId = ViewState.Get<int>("CategoryIdToMatch");

			Context.ExecuteSafely(() => DoCreateNewCode(categoryId));
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e) {
			base.OnInit(e);

			// Add object datasources.
			var ds1 = new MyObjectDataSource(typeof(MyLib.Data.CodeProvider).AssemblyQualifiedName, "FindCodes");
			ds1.ID = "ObjectDataSource1";
			ds1.EnableCaching = false;
			ds1.EnablePaging = false;

			ds1.SelectParameters.Add(new MyViewStateParameter {
				Name = "categoryId",
				Type = TypeCode.String,
				Key = "CategoryIdToMatch"
			});

			var ds2 = new MyObjectDataSource(typeof(MyLib.Data.CodeProvider).AssemblyQualifiedName, "FindCode");
			ds2.UpdateMethod = "SaveCode";
			ds2.ID = "ObjectDataSource2";
			ds2.EnableCaching = false;
			ds2.EnablePaging = false;

			ds2.SelectParameters.Add(new MyViewStateParameter {
				Name = "categoryId",
				Type = TypeCode.Int32,
				Key = "EditCategoryId"
			});
			ds2.SelectParameters.Add(new MyViewStateParameter {
				Name = "value",
				Type = TypeCode.String,
				Key = "EditValue"
			});

			ds2.UpdateParameters.Add("categoryId", TypeCode.Int32, "");
			ds2.UpdateParameters.Add("value", TypeCode.String, "");
			ds2.UpdateParameters.Add("text", TypeCode.String, "");
			ds2.UpdateParameters.Add("parent", TypeCode.String, "");
			ds2.UpdateParameters.Add(new MyViewStateParameter {
				Name = "insertFlag",
				Type = TypeCode.Boolean,
				Key = "InsertFlag"
			});

			Controls.Add(ds1);
			Controls.Add(ds2);

			// Assign event handlers.
			var formView1 = this.FindDescendantControl<MyFormView>("FormView1");
			formView1.DataSourceID = ds2.ID;

			var gridView1 = this.FindDescendantControl<MyGridView>("GridView1");
			gridView1.DataSourceID = ds1.ID;
			gridView1.AllowPaging = false;

			formView1.Saved += new EventHandler<MyFormViewSavedEventArgs>(OnFormView1Saved);
			formView1.Cancelled += new EventHandler<MyFormViewCommandEventArgs>(OnFormView1Cancelled);

			gridView1.RowCommand += new GridViewCommandEventHandler(OnGridView1RowCommand);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		protected override void OnLoad(EventArgs e) {
			base.OnLoad(e);

			this.Title = Properties.Main.TitleCodes;

			if (!IsPostBack) {
				this.FindDescendantControl<MyPanel>("Panel1").CopyValuesToViewState(ViewState);

				Context.ExecuteSafely(DoQuery);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="source"></param>
		/// <param name="args"></param>
		/// <returns></returns>
		protected override bool OnBubbleEvent(object source, EventArgs args) {
			bool causesValidation = false;
			string validationGroup = string.Empty;

			if (args is CommandEventArgs) {
				IButtonControl commandSource = source as IButtonControl;
				if (commandSource != null) {
					causesValidation = commandSource.CausesValidation;
					validationGroup = commandSource.ValidationGroup;
				}

				var cargs = (CommandEventArgs)args;

				if (string.Equals(cargs.CommandName, "Query", StringComparison.OrdinalIgnoreCase)) {
					HandleQuery(causesValidation, validationGroup);
					return true;
				} else if (string.Equals(cargs.CommandName, "CreateNew", StringComparison.OrdinalIgnoreCase)) {
					HandleCreateNew(causesValidation, validationGroup);
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnFormView1Saved(object sender, MyFormViewSavedEventArgs e) {
			ViewState["EditValue"] = "";

			Context.ExecuteSafely(DoQuery);

			Context.ExecuteSafely(UpdateCodeCache);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnFormView1Cancelled(object sender, MyFormViewCommandEventArgs e) {
			ViewState["EditValue"] = "";
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		protected void OnGridView1RowCommand(object sender, GridViewCommandEventArgs e) {
			var arg = (string)e.CommandArgument;

			var idx = arg.IndexOf('_');

			if (idx < 0) {
				return;
			}

			var categoryId = arg.Substring(0, idx);
			var value = arg.Substring(idx + 1);

			Action act;
			switch (e.CommandName) {
				case "EditCode":
					act = () => DoEditCode(Convert.ToInt32(categoryId), value);
					break;
				case "DeleteCode":
					act = () => DoDeleteCode(Convert.ToInt32(categoryId), value);
					break;
				default:
					return;
			}

			Context.ExecuteSafely(act);
		}

	} // end of CodePage.
}
